package com.neuedu.servlet;

import com.alibaba.fastjson2.JSONObject;
import com.neuedu.base.R;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 许中
 * @date 2024-09-06 09:16:48
 */
@WebServlet(urlPatterns = "/*", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {

    public static final String CONTROLLER_PACKAGE_NAME="com.neuedu.controller";
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");

        //User
        //UserController
        //http://localhost:8080/web_war_exploded/User/signIn
        //uri:         /web_war_exploded/User/signIn
        //contextPath: /web_war_exploded

        String uri=request.getRequestURI();
        String contextPath=request.getContextPath();
        //截下来之后：User/signIn
        uri=uri.substring(contextPath.length()+1);

        ServletInputStream inputStream = request.getInputStream();
        StringBuilder params=new StringBuilder();
        byte [] bytes=new byte[1024*1024];
        int len;
        while((len=inputStream.read(bytes))!=-1){
            params.append(new String(bytes,0,len,"UTF-8"));
        }
        if(inputStream!=null){
            inputStream.close();
        }

        if(uri.indexOf("/")<0){
            //请求错误
            response.getWriter().print(R.error("请求必须用/分隔类和方法"));
            return;
        }

        String [] uriString=uri.split("/");
        String className=uriString[0]+"Controller";
        String methodName=uriString[1];

        try {
            Class<?> clazz = Class.forName(CONTROLLER_PACKAGE_NAME + "." + className);
            Method method=null;
            try {
                method=clazz.getMethod(methodName, JSONObject.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                //写上传文件的情况
            }
            //方法不是静态的，必须要使用对象才能调用。
            Object controllerObject = clazz.newInstance();
            //执行指定的方法，拿到一个返回值
            Object result=method.invoke(controllerObject,JSONObject.parseObject(params.toString()));
            //把result也就是R，输出给前端
            response.getWriter().print(result.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");

        String uri=request.getRequestURI();
        String contextPath = request.getContextPath();
        Map<String, String[]> parameterMap = request.getParameterMap();

        if(parameterMap==null){
            parameterMap=new HashMap<>();
        }

        uri=uri.substring(contextPath.length()+1);
        if(uri.indexOf("/")<0){
            response.getWriter().print(R.error("请求必须用/分隔类和方法"));
            return;
        }
        String [] uriString=uri.split("/");
        String className=uriString[0]+"Controller";
        String methodName=uriString[1];

        try {

            Class<?> clazz = Class.forName(CONTROLLER_PACKAGE_NAME + "." + className);
            //调用方法
            Object object=clazz.newInstance();
            Method method=null;
            try {
                method=clazz.getMethod(methodName,Map.class);
            } catch (NoSuchMethodException e) {
                //e.printStackTrace();
                System.out.println("Map为参数的重载未找到，现在使用HttpServletRequest,HttpServletResponse的重载");
                //方法未找到的情况
                method=clazz.getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
                method.invoke(object,request,response);
                return ;
            }
            Object result = method.invoke(object, parameterMap);

            response.getWriter().print(result.toString());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}
